package kvoog.arkanoid.physics;

import kvoog.arkanoid.core.ArkanoidEntityFactory;
import kvoog.arkanoid.core.Ball;
import kvoog.arkanoid.core.Bounds;
import kvoog.arkanoid.core.Brick;
import kvoog.arkanoid.core.Health;
import kvoog.arkanoid.core.Player;
import kvoog.arkanoid.core.Trigger;

import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.managers.PlayerManager;
import com.artemis.systems.EntityProcessingSystem;
import com.artemis.utils.ImmutableBag;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.Contact;

public class CollisionResponseSystem extends EntityProcessingSystem {

	@Mapper private ComponentMapper<CollisionEvent> clm;
	@Mapper private ComponentMapper<Player> plm;
	@Mapper private ComponentMapper<Ball> ballm;
	@Mapper private ComponentMapper<Brick> brickm;
	@Mapper private ComponentMapper<Bounds> boundsm;
	@Mapper private ComponentMapper<Trigger> trm;
	@Mapper private ComponentMapper<Health> hlm;
	
	@SuppressWarnings("unchecked")
	public CollisionResponseSystem() {
		super(Aspect.getAspectForAll(CollisionEvent.class));
	}

	@Override
	protected void process(Entity e) {
		
		CollisionEvent collision = clm.get(e);
		CollisionEvent.CollisionType type = collision.type;
		Contact contact = collision.contact;
		
		// ovde iskace null pointer ... verovatno se ukloni cigla pre ove obrade kolizije
		// nije bitno za sada
		Body b1 = contact.getFixtureA().getBody();
		Body b2 = contact.getFixtureB().getBody();
		
		Entity e1 = (Entity) contact.getFixtureA().getBody().getUserData();
		Entity e2 = (Entity) contact.getFixtureB().getBody().getUserData();
		
		switch (type) {
			
		case BEGIN_CONTACT:		
			if (ballm.getSafe(e1) != null) {
				if (trm.getSafe(e2) != null)
					handleBallTrigger(e1, e2);
			}
			if (ballm.getSafe(e2) != null) {
				if (trm.getSafe(e1) != null)
					handleBallTrigger(e2, e1);
			}
			break;

		case END_CONTACT:
			Body ball_body = null;
			if (ballm.getSafe(e1) != null) {
				if (brickm.getSafe(e2) != null)
					handleBallBrick(e1, e2);
				
				ball_body = b1;
			}
			if (ballm.getSafe(e2) != null) {
				if (brickm.getSafe(e1) != null)
					handleBallBrick(e2, e1);
				
				ball_body = b2;
			}
			
			if (ball_body != null) {
				Vector2 vel = ball_body.getLinearVelocity();
				vel.nor();
				vel.mul(3);
				ball_body.setLinearVelocity(vel);
			}			
			break;
			
		case PRE_SOLVE:
			break;
			
		case POST_SOLVE:
			break;
		}
		
		world.deleteEntity(e);
	}
	
	private void handleBallBrick(Entity e1, Entity e2) {
		ImmutableBag<Entity> ple = world.getManager(PlayerManager.class).getEntitiesOfPlayer("player1");
		Player player = plm.get(ple.get(0));
		player.score = player.score+1;
		
		world.deleteEntity(e2);
	}
	
	private void handleBallTrigger(Entity e1, Entity e2) {
		ImmutableBag<Entity> ple = world.getManager(PlayerManager.class).getEntitiesOfPlayer("player1");
				
		world.deleteEntity(e1);
		
		Player player = plm.get(ple.get(0));
		Health health = hlm.get(ple.get(0));
		health.health = health.health-1;
		if (health.health > 0)
			ArkanoidEntityFactory.getInstance().createBall(4f, 1f, 0.07f);
		else {
			player.fsm.changeState("gameover");
		}
	}
}
